import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;

import xml.utils.XmlDocument;
import xml.utils.XmlException;
import xml.utils.XmlNode;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.swing.JTextArea;
import java.awt.BorderLayout;


public class ClientWindow{

	private JFrame frame;
	public JFrame frmServermanager;
	XmlDocument xmlConfiguration;
	XmlNode xmlRoot;
	String strLog;
	File fileLog;
	URL urlPath;
	String strPath;
	String strFileName;
	DateFormat dateFormat;
	Date date;
	String strHost;
	String strRegistry;
	AccessDBInterface accClient;
	List<XmlNode> lstHost;
	List<XmlNode> lstRegistry;
	String strUserID;
	String strPassword;
	String strServer;
	int iServer;
	int numberofservers;
	String strReturnValues;
	LoginDialog logdlg;
	boolean bFocus;
	
	private JTextArea txtClientLog;
	private JMenuBar menuBar;
	private JMenu mnMain;
	private JMenuItem mntmLoadConfiguration;
	private JMenuItem mntmLogIn;
	private JMenuItem mntmExit;
	private JMenuItem mntmLogOut;
	private JMenu mnFunction;
	private JMenuItem mntmAddUser;
	private JMenuItem mntmCheckAllReceipt;
	private JMenuItem mntmSearchProduct;
	private JMenuItem mntmDeleteProduct;
	private JMenuItem mntmCheckReceiptNote;
	private JMenuItem mntmAddDeliveryNote;
	private JMenuItem mntmUpdateProduct;
	private JMenuItem mntmUpdateUser;
	private JMenuItem mntmDeleteUser;
	private JMenuItem mntmAddProduct;
	private JMenuItem mntmAddReceiptNote;


	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					ClientWindow window = new ClientWindow();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public ClientWindow() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	@SuppressWarnings("deprecation")
	private void initialize() {
		frame = new JFrame();
		frame.setBounds(100, 100, 483, 323);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		//Variables' Initialization
		urlPath = ServerWindow.class.getResource("ClientWindow.class");
		strPath = urlPath.toString();
		strPath = strPath.substring(6, strPath.lastIndexOf("/") + 1);
		strLog = new String();
		dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
		date = new Date();
		strFileName = new String("logClient" + date.getDate() + "." + date.getMonth() + "." + (date.getYear() + 1900) + "_" + date.getHours() + "." + date.getMinutes() + "." + date.getSeconds() + ".txt");
		fileLog = new File(strPath + strFileName);
		strUserID = new String();
		strPassword = new String();
		strServer = new String();
		iServer = new Integer(0);
		bFocus = true;
		
		//Focus listener
		
		//Control's Initialization
		menuBar = new JMenuBar();
		frame.setJMenuBar(menuBar);
		
		mnMain = new JMenu("Main");
		menuBar.add(mnMain);
		
		mntmLoadConfiguration = new JMenuItem("Load Configuration");
		mnMain.add(mntmLoadConfiguration);
		
		mntmLogIn = new JMenuItem("Log in");
		mnMain.add(mntmLogIn);
		mntmLogIn.setEnabled(false);
		
		mntmLogOut = new JMenuItem("Log out");
		mnMain.add(mntmLogOut);
		mntmLogOut.setEnabled(false);
		
		mntmExit = new JMenuItem("Exit");
		mnMain.add(mntmExit);
		
		mnFunction = new JMenu("Function");
		menuBar.add(mnFunction);
		mnFunction.setEnabled(false);
		
		mntmAddProduct = new JMenuItem("Add Product");
		mnFunction.add(mntmAddProduct);
		mntmAddProduct.setEnabled(false);
		
		mntmUpdateProduct = new JMenuItem("Update Product");
		mnFunction.add(mntmUpdateProduct);
		mntmUpdateProduct.setEnabled(false);
		
		mntmDeleteProduct = new JMenuItem("Delete Product");
		mnFunction.add(mntmDeleteProduct);
		mntmDeleteProduct.setEnabled(false);
		
		mntmAddReceiptNote = new JMenuItem("Add Receipt Note");
		mnFunction.add(mntmAddReceiptNote);
		mntmAddReceiptNote.setEnabled(false);
		
		mntmCheckReceiptNote = new JMenuItem("Check Receipt Note");
		mnFunction.add(mntmCheckReceiptNote);
		mntmCheckReceiptNote.setEnabled(false);
		
		mntmCheckAllReceipt = new JMenuItem("Check All Receipt Note");
		mnFunction.add(mntmCheckAllReceipt);
		mntmCheckAllReceipt.setEnabled(false);
		
		mntmSearchProduct = new JMenuItem("Search Product");
		mnFunction.add(mntmSearchProduct);
		mntmSearchProduct.setEnabled(false);
		
		mntmAddUser = new JMenuItem("Add User");
		mnFunction.add(mntmAddUser);
		mntmAddUser.setEnabled(false);
		
		mntmUpdateUser = new JMenuItem("Update User");
		mnFunction.add(mntmUpdateUser);
		mntmUpdateUser.setEnabled(false);
		
		mntmDeleteUser = new JMenuItem("Delete User");
		mnFunction.add(mntmDeleteUser);
		mntmDeleteUser.setEnabled(false);
		
		mntmAddDeliveryNote = new JMenuItem("Add Delivery Note");
		mnFunction.add(mntmAddDeliveryNote);
		mntmAddDeliveryNote.setEnabled(false);
		
		frame.getContentPane().setLayout(null);
		
		txtClientLog = new JTextArea();
		txtClientLog.setBounds(0, 0, 467, 264);
		frame.getContentPane().add(txtClientLog);
		
		//Event Handling
		mntmLoadConfiguration.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				try {
					xmlConfiguration = new XmlDocument();
					xmlRoot = xmlConfiguration.parse(strPath + "servers.xml");
					
					writeFileLog("Loading Configuration...\n");
					txtClientLog.setText(readFileLog(fileLog));					
					
					numberofservers = Integer.parseInt(xmlRoot.getTagValue("numberofservers"));
					writeFileLog("Number of servers: " + numberofservers + "\n");
					txtClientLog.setToolTipText(readFileLog(fileLog));
					
					lstHost = xmlRoot.getNodesByTagName("host");
					lstRegistry = xmlRoot.getNodesByTagName("registry");
					
					for (int i = 0; i < numberofservers; i++) {
						writeFileLog("Server IP: " + lstHost.get(i).getNodeValue() + ", with registry: " + lstRegistry.get(i).getNodeValue() + "\n");
					}
					txtClientLog.setText(readFileLog(fileLog));

					writeFileLog("OK!!!\n");
					txtClientLog.setText(readFileLog(fileLog));
					
					mntmLogIn.setEnabled(true);
				} catch (XmlException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (FileNotFoundException e2) {
					// TODO Auto-generated catch block
					e2.printStackTrace();
				}
			}
		});

		mntmLogIn.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				// TODO Auto-generated method stub
				bFocus = false;
				logdlg = new LoginDialog(ClientWindow.this, frame, true, numberofservers);
				logdlg.setVisible(true);
			}
		});
		
		mntmLogOut.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				// TODO Auto-generated method stub
				String str = "" + logdlg.dlgstrUserID + " " + logdlg.dlgstrPassword + " " + logdlg.dlgiServer;

				writeFileLog(str);
				try {
					txtClientLog.setText(readFileLog(fileLog));
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
		
		mntmExit.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				// TODO Auto-generated method stub
				frame.setVisible(false);
			}
		});
		
		mntmAddUser.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				// TODO Auto-generated method stub
				AddUserDialog dlgAddUser = new AddUserDialog(accClient, numberofservers);
				dlgAddUser.setVisible(true);
			}
		});
		
		mntmUpdateUser.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				UpdateUserDialog dlgUpdateUser = new UpdateUserDialog(accClient, numberofservers);
				dlgUpdateUser.setVisible(true);
			}
		});
	}
	
	public void realLogin() throws FileNotFoundException {
		strUserID = logdlg.dlgstrUserID;
		strPassword = logdlg.dlgstrPassword;
		iServer = logdlg.dlgiServer;
		
		String strNamingLookup = "rmi://" + lstHost.get(iServer).getNodeValue() + "/" + lstRegistry.get(iServer).getNodeValue();
		try {
			accClient = (AccessDBInterface)Naming.lookup(strNamingLookup);
			int iResult = accClient.checkLoginInformation(strUserID, strPassword, iServer + 1);
			
			switch (iResult) {
			case -1:
				JOptionPane.showMessageDialog(null, "Wrong Server!!!");
				break;
			case 0:
				JOptionPane.showMessageDialog(null, "Incorrect UserID or Password!!!");
				break;
			case 1:
				JOptionPane.showMessageDialog(null, "You are General Manager. Login succeeded. You can connect to any server.");
				mnFunction.setEnabled(true);
				mntmCheckAllReceipt.setEnabled(true);
				mntmSearchProduct.setEnabled(true);
				break;
			case 2:
				JOptionPane.showMessageDialog(null, "You are Admin. Login succeeded.");
				mnFunction.setEnabled(true);
				mntmAddUser.setEnabled(true);
				mntmDeleteUser.setEnabled(true);
				mntmUpdateUser.setEnabled(true);
				break;
			case 3:
				JOptionPane.showMessageDialog(null, "You are Warehouse Manager. Login succeeded.");
				mnFunction.setEnabled(true);
				mntmAddProduct.setEnabled(true);
				mntmDeleteProduct.setEnabled(true);
				mntmUpdateProduct.setEnabled(true);
				mntmCheckReceiptNote.setEnabled(true);
				break;
			case 4:
				JOptionPane.showMessageDialog(null, "You are Deliverer. Login succeeded.");
				mnFunction.setEnabled(true);
				mntmAddDeliveryNote.setEnabled(true);
				break;
			}

			mntmLogOut.setEnabled(true);
		} catch (MalformedURLException | RemoteException e) {
			//TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NotBoundException e) {
			JOptionPane.showMessageDialog(null, "Wrong server");
		}
	}
	
	public void writeFileLog(String strCurrentLog) {
		try {
			BufferedWriter writer = new BufferedWriter(new FileWriter(fileLog, true));
			writer.write(strCurrentLog);
			writer.close();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}		
	}
	
	public String readFileLog(File fileLog) throws FileNotFoundException {
		String everything = new String();
	    BufferedReader br = new BufferedReader(new FileReader(fileLog));
	    try {
	        StringBuilder sb = new StringBuilder();
	        String line = br.readLine();

	        while (line != null) {
	            sb.append(line);
	            sb.append("\n");
	            line = br.readLine();
	        }
	        everything = sb.toString();
	    } catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
	        try {
				br.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	    }
	    
	    return everything;
	}

	public JTextArea getTxtClientLog() {
		return txtClientLog;
	}
	public JMenuBar getMenuBar() {
		return menuBar;
	}
	public JMenu getMnMain() {
		return mnMain;
	}
	public JMenuItem getMntmLoadConfiguration() {
		return mntmLoadConfiguration;
	}
	public JMenuItem getMntmLogIn() {
		return mntmLogIn;
	}
	public JMenuItem getMntmExit() {
		return mntmExit;
	}
	public JMenuItem getMntmLogOut() {
		return mntmLogOut;
	}
	public JMenu getMnFunction() {
		return mnFunction;
	}
	public JMenuItem getMntmAddUser() {
		return mntmAddUser;
	}
	public JMenuItem getMntmCheckAllReceipt() {
		return mntmCheckAllReceipt;
	}
	public JMenuItem getMntmSearchProduct() {
		return mntmSearchProduct;
	}
	public JMenuItem getMntmDeleteProduct() {
		return mntmDeleteProduct;
	}
	public JMenuItem getMntmCheckReceiptNote() {
		return mntmCheckReceiptNote;
	}
	public JMenuItem getMntmAddDeliveryNote() {
		return mntmAddDeliveryNote;
	}
	public JMenuItem getMntmUpdateProduct() {
		return mntmUpdateProduct;
	}
	public JMenuItem getMntmUpdateUser() {
		return mntmUpdateUser;
	}
	public JMenuItem getMntmDeleteUser() {
		return mntmDeleteUser;
	}
	public JMenuItem getMntmAddProduct() {
		return mntmAddProduct;
	}
	public JMenuItem getMntmAddReceiptNote() {
		return mntmAddReceiptNote;
	}
}

